__author__ = 'admin zhoushuang'

import gvars
import socket
import os
import os.path
import time
import shutil
import tempfile
import base64


from base_handler import *
from common_functions import *


class mod_replacecfg(BaseHandler):
    """ Replace values in properties files.

    According to autocfg.txt file to replace values in properties file.
    Request Parameters:
        module  = mod_replacecfg
        dir     = ...               # autocfg.txt in this dir
        autocfg = ...               # optional,  default value is autocfg.txt

    """
    def __init__(self):
        self.dict = {}
        self.dir = ''
        self.autocfg = ''
        self.timestamp = None
        super(mod_replacecfg, self).__init__()

    def handle(self, reqdict):
        self.timestamp = time.strftime('%Y%M%d%H%M%S', time.localtime())
        try:
            params = extract_param(reqdict, (('dir', 1), ('autocfg', 0), ('base64', 0)))
        except ValueError:
            self.echo.write('#ERROR\t Request Parameter is wrong. reqdict = {}'.format(reqdict))
            return

        self.dir = params['dir']
        self.autocfg = self.dir + os.sep + 'autocfg.txt'
        b64 = params.get('base64', None)
        if os.path.isfile(self.autocfg) and b64:
            bakautocfg = self.autocfg + '.' + self.timestamp
            shutil.copy(self.autocfg, bakautocfg)
            with open(self.autocfg, 'w') as fout:
                bt = base64.b64decode(b64)
                fout.write(bt)
                fout.flush()

        self.parse(self.autocfg)
        self.replace()

    def handle_request_side(self, reqdict, address_tuple):
        params = extract_param(reqdict, (('dir', 1), ('autocfg', 0), ('base64', 0)))
        cfgfile = params.get('autocfg', None)
        if cfgfile:
            b64 = file2base64(cfgfile)
            reqdict['base64'] = b64

        BaseHandler.handle_request_side(self, reqdict, address_tuple)






    def parse(self, autocfgfile):
        """Parse autocfg.txt(defualt), get replacing rules stored in self.dict.

        :param autocfgfile: the path of autocfig.txt
        :return:    None
        """
        self.dict = {}
        with open(autocfgfile, 'rt') as f:
            fname = ''
            spflag = False
            spip = []
            for line in f:
                if not line.isspace():
                    line = line.strip()
                    if line.startswith(gvars.ACFG_FITAG):
                        fname = line.split()[1]
                        spflag = False
                        spip = []
                        if not self.dict.get(fname):
                            self.dict[fname] = {}

                    elif line.startswith(gvars.ACFG_IPTAG):
                        spip = line.split()[1:]
                        spflag = True

                    elif line.startswith('#'):
                        pass

                    else:
                        kv = line.split('=', 1)
                        if len(kv) == 2:
                            if not fname.isspace():
                                if not spflag:
                                    if not self.dict[fname].get('DEFAULT'):
                                        self.dict[fname]['DEFAULT'] = {}
                                    self.dict[fname]['DEFAULT'][kv[0].strip()] = kv[1].strip()
                                else:
                                    for ip in spip:
                                        if not self.dict[fname].get(ip):
                                            self.dict[fname][ip] = {}
                                        self.dict[fname][ip][kv[0].strip()] = kv[1].strip()

    def replace(self):
        """ Replace values in properies file one bye one.

        According to self.dict to replacing, and make bakeup with timestamp

        :return: None
        """
        localip = socket.gethostbyname(socket.gethostname())
        # print 'local ip:', localip

        for fn, propdict in self.dict.items():
            fname = self.dir + os.sep + fn
            defdict = propdict['DEFAULT']
            sipdict = propdict.get(localip, None)
            try:
                bakfile = fname + '.' + self.timestamp
                shutil.copy(fname, bakfile)
                tmpfile = tempfile.mktemp('.txt')
                # print 'tmpfile:', tmpfile
                # print 'fname :',fname
                with open(tmpfile, 'wt') as fout, open(fname, 'rt') as fin:
                    for line in fin:
                        stline = line.strip()
                        # print 'stline=',stline
                        if stline.startswith('#') or stline.isspace():
                            # print 'line=',line
                            fout.write(line)
                        else:
                            kv = stline.split('=', 1)
                            if len(kv) == 2:
                                if sipdict and kv[0].strip() in sipdict.keys():
                                    line = kv[0] + '=' + sipdict[kv[0].strip()] + '\n'
                                elif kv[0].strip() in defdict.keys():
                                    line = kv[0] + '=' + defdict[kv[0].strip()] + '\n'
                                else:
                                    pass
                            fout.write(line)
                shutil.copy(tmpfile, fname)
                self.echo.write("##########{:^80}###########\n".format(fname + ' OK'))
            except Exception as e:
                self.echo.write('#ERROR replace {}\n'.format(fname))
                self.echo.write('#ERROR {}\n'.format(e))


def gethandler():
    return gethandler.cache


gethandler.cache = mod_replacecfg()

if __name__ == '__main__':
    rep = mod_replacecfg()
    rep.parse('autocfg.txt')
    rep.echo = sys.stdout
    reqdict = {'dir': 'C:\\Users\\admin\\PycharmProjects\\ophelper'}
    rep.handle(reqdict)

    # print rep.dict